package br.edu.unifei.mestrado.mn;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import br.edu.unifei.mestrado.commons.graph.GraphWrapper;
import br.edu.unifei.mestrado.commons.partition.BestPartition;
import br.edu.unifei.mestrado.db.graph.GraphDB;
import br.edu.unifei.mestrado.kl.BKL;
import br.edu.unifei.mestrado.kl.KL;
import br.edu.unifei.mestrado.kl.KLNeoDB;

public class MultinivelNeoDB extends TwoWayMultinivel {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	protected GraphDB grafo = null;
	private String dbFileName;
	private boolean REUSE_DB = false;

	public MultinivelNeoDB(boolean reuseDB, String graphFileName) {
		this.dbFileName = graphFileName;

		// UTIL: está usando GraphWrapper.NO_LEVEL ao inves de zero, para aproveitar o grafo feito pelo
		// gerador de grafos
		grafo = new GraphDB(reuseDB, dbFileName, GraphWrapper.NO_LEVEL);
	}

	@Override
	public void readGraph() {
		grafo.readGraph();
	}

	@Override
	protected GraphWrapper createNewGraph(Integer level) {
		// UTIL: os grafos de niveis contraidos nao podem reusar o banco
		GraphDB grafo = new GraphDB(REUSE_DB, dbFileName, level);
		return grafo;
	}

	protected BKL getBKLObject(final GraphWrapper newGrafo) {
		BKLNeoDB bkl = new BKLNeoDB((GraphDB) newGrafo);
		return bkl;
	}

	@Override
	protected GraphWrapper getGrafo() {
		return grafo;
	}

	protected KL getKLObject(final GraphWrapper newGrafo) {
		// TODO: Verificar se realmente precisar ser o KLNeoDB aqui.
		KLNeoDB kl = new KLNeoDB((GraphDB) newGrafo);
		return kl;
	}

	@Override
	protected BestPartition executePartition(GraphWrapper grafo) {
		long delta = System.currentTimeMillis();
		KL kl = getKLObject(grafo);

		BestPartition result = kl.executeKL();
		result.printSets();
		delta = System.currentTimeMillis() - delta;
		logger.warn("Tempo gasto no KL: " + delta + " ms");
		return result;
	}

	@Override
	protected BestPartition refineGraph(GraphWrapper graph, int level) {
		BKL bkl = getBKLObject(graph);
		BestPartition part = bkl.executeBKL(level);
		return part;
	}

	@Override
	public void initView(GraphWrapper initialGraph) {
		// no view
	}

	@Override
	public void setShowView(boolean showView) {
		// no view
	}

	@Override
	public void updateView(GraphWrapper grafo, int level, String it, int cutWeight) {
		// no view
	}

	@Override
	public void updateViewCoarsed(GraphWrapper grafo, int level, String it, int cutWeight) {
		// no view
	}

	@Override
	public void repaint() {
		// no view
	}
}
